﻿using System;
using System.Runtime.Serialization;
using System.Text;
using EPiServer.Core;

namespace OpenWaves.EPiServer.CustomProperties
{
    [Serializable]
    public class PropertySerializationException : Exception
    {
        private const string PropertyNameKey = "PropertyName";

        private const string PageLinkKey = "PageLink";

        private const string PropertyValueKey = "PropertyValue";

        private readonly PageReference pageLink;

        private readonly string propertyName;

        private readonly string propertyValue;

        public PropertySerializationException()
        {
        }

        public PropertySerializationException(string message)
            : base(message)
        {
        }

        public PropertySerializationException(string message, Exception inner)
            : base(message, inner)
        {
        }

        protected PropertySerializationException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            if (info != null)
            {
                this.propertyName = info.GetString(PropertyNameKey);
                this.pageLink = (PageReference)info.GetValue(PageLinkKey, typeof(PageReference));
                this.propertyValue = info.GetString(PropertyValueKey);
            }
        }

        public PropertySerializationException(
            string message, string propertyName, PageReference pageLink, string propertyValue)
            : base(BuildMessage(message, propertyName, pageLink, propertyValue))
        {
            this.propertyName = propertyName;
            this.pageLink = pageLink;
            this.propertyValue = propertyValue;
        }

        public PropertySerializationException(
            string message, string propertyName, PageReference pageLink, object propertyValue, Exception innerException)
            : base(BuildMessage(message, propertyName, pageLink, propertyValue), innerException)
        {
            this.propertyName = propertyName;
            this.pageLink = pageLink;
            this.propertyValue = propertyValue != null ? propertyValue.ToString() : null;
        }

        public string PropertyName
        {
            get { return this.propertyName; }
        }

        public PageReference PageLink
        {
            get { return this.pageLink; }
        }

        public string PropertyValue
        {
            get { return this.propertyValue; }
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);

            info.AddValue(PropertyNameKey, this.propertyName);
            info.AddValue(PageLinkKey, this.PageLink);
            info.AddValue(PropertyValueKey, this.propertyValue);
        }

        private static string BuildMessage(
            string message, string propertyName, PageReference pageLink, object propertyValue)
        {
            StringBuilder sb = new StringBuilder(message);

            sb.AppendFormat(
                " Property name: '{0}', Page link: '{1}', Property value: '{2}'.", propertyName, pageLink, propertyValue);

            return sb.ToString();
        }
    }
}